package name.as3.cmdFrameworks.core
{
import flash.display.Sprite;
import flash.utils.Dictionary;
import flash.utils.SafeGlobalOwner;
import flash.utils.SafeGlobalProxy;

import name.as3.cmdFrameworks.interfaces.ICommand;
import name.as3.cmdFrameworks.interfaces.IFacade;
import name.as3.cmdFrameworks.interfaces.IManager;
import name.as3.cmdFrameworks.interfaces.IMediatorManagerDelegate;
import name.as3.cmdFrameworks.interfaces.INotification;
import name.as3.cmdFrameworks.manager.MediatorManager;
import name.as3.cmdFrameworks.manager.delegate.MediatorManagerDelegate;

public class Facade extends SafeGlobalOwner implements IFacade
{
	protected static var sp_mapInstance:Dictionary = new Dictionary();
	private const m_mapCommand:Dictionary = new Dictionary();
	private const m_mapManager:Dictionary = new Dictionary();
	/**
	 * 面板管理器
	 */
	private var m_uiManager:IMediatorManagerDelegate;
	private var m_blAllowDisposeSG:Boolean;
	/**
	 * SafeGlobal字典
	 */
	private var m_global:Dictionary;
	private var m_contApp:Sprite;
	/**
	 *
	 */
	public function Facade(strKey:String = null)
	{
		if (sp_mapInstance[strKey] != null)
		{
			throw new Error("Repeated Facade Key! ");
		}
		else
		{
			sp_mapInstance[strKey] = this;
		}
	}
//==================================================================================================
// public
//==================================================================================================
	override public function dispose():void
	{
		m_blAllowDisposeSG = true;
		if (sg != null)
		{
			sg.dispose();
		}
	}
	/**
	 * 初始函数
	 */
	public function init(contApp:Sprite, sgDefault:* = null):void
	{
		m_contApp = contApp;
		if (sgDefault != null)
		{
			super.sg = new SafeGlobalProxy();
			super.sg.initiator = this;
			super.sg[null] = sgDefault;
		}
	}
	/**
	 *
	 */
	public function get allowDisposeSG():Boolean
	{
		return m_blAllowDisposeSG;
	}
	/**
	 * 获取容器
	 */
	public function get appContainer():Sprite
	{
		return m_contApp;
	}
	/**
	 * 添加管理器
	 */
	public function addManager(strType:String, obManager:IManager):void
	{
		if (strType != null && obManager != null)
		{
			if (null == m_mapManager[strType])
			{
				/*不必在Else中抛错
				*/
				m_mapManager[strType] = obManager;
				obManager.setFacade(this, super.sg);
			}
		}
		else
		{
			throw new Error("Error Manager or ManagerType");
		}
	}
	/**
	 * 移除管理器
	 */
	public function removeManager(strType:String):void
	{
		if (strType != null)
		{
			m_mapManager[strType] = null;
		}
	}
	/**
	 * 获取管理器
	 */
	public function getManager(strType:String):IManager
	{
		if (strType != null)
		{
			return m_mapManager[strType];
		}
		return null;
	}
	/**
	 * 发送消息
	 */
	public function sendNotification(strType:String, obData:* = null):void
	{
		var note:Notification = new Notification(strType, obData);
		note.setFacade(this, super.sg);
		note.dispatch();
	}
	/**
	 * 执行命令
	 */
	public function invokeCommand(strType:String,
								  cCommand:Class,
								  obData:* = null,
								  blIsOneoff:Boolean = false):void
	{
		this.addCommand(strType, cCommand);
		this.sendNotification(strType, obData);
	}
	/**
	 * 获取面板管理器
	 */
	public function get uiManager():IMediatorManagerDelegate
	{
		if (null == m_uiManager)
		{
			m_uiManager = new MediatorManagerDelegate();
			m_uiManager.manager = new MediatorManager();
			m_uiManager.manager.setFacade(this, super.sg);
		}
		return m_uiManager;
	}
	/**
	 * 执行命令
	 */
	public function executeCommand(obNote:INotification):void
	{
		if (obNote != null)
		{
			var strType:String = obNote.type;
			if (strType != null)
			{
				var cCommand:Class = m_mapCommand[strType];
				var obCommand:ICommand = new cCommand();
				obCommand.setFacade(this, super.sg);
				obCommand.execute(obNote);
			}
		}
	}
	/**
	 * 添加命令
	 */
	public function addCommand(strType:String, cCommand:Class):void
	{
		if (strType != null && cCommand != null)
		{
			if (null == m_mapCommand[strType])
			{
				/*不必在Else中抛错
				*/
				m_mapCommand[strType] = cCommand;
			}
		}
		else
		{
			throw new Error("Error Command or CommandType");
		}
	}
	/**
	 * 移除命令
	 */
	public function removeCommand(strType:String, cCommand:Class):void
	{
		if (strType != null && cCommand != null)
		{
			m_mapCommand[strType] = null;
		}
	}
	/**
	 * 检查命令
	 */
	public function hasCommand(strType:String):Boolean
	{
		if (strType != null)
		{
			return (m_mapCommand[strType] != null);
		}
		return false;
	}
}
}